#include "registerdialog.h"
#include "ui_registerdialog.h"

#include "httpmgr.h"

RegisterDialog::RegisterDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::RegisterDialog),
    _countdown(10)
{
    ui->setupUi(this);

    ui->err_tip->setProperty("state", "normal");
    repolish(ui->err_tip);
    ui->stackedWidget->setCurrentWidget(ui->page);

    // 连接http请求注册模块的信号
    connect(HttpMgr::GetInstance().get(), &HttpMgr::sig_reg_mod_finish,
            this, &RegisterDialog::slot_reg_mod_finish);

    // 初始化http请求的回包逻辑
    initHttpHandlers();

    // 输入框错误提示
    ui->err_tip->clear();
    connect(ui->user_edit, &QLineEdit::textChanged, this, [this](){
        checkUserValid();
    });
    connect(ui->email_edit, &QLineEdit::textChanged, this, [this](){
        checkEmailValid();
    });
    connect(ui->pass_edit, &QLineEdit::textChanged, this, [this](){
        checkPassValid();
    });
    connect(ui->confirm_edit, &QLineEdit::textChanged, this, [this](){
        checkConfirmValid();
    });
    connect(ui->verify_edit, &QLineEdit::textChanged, this, [this](){
        checkVerifyValid();
    });

    // 初始化密码和确认密码可视标签的状态
    ui->pass_visible->setCursor(Qt::PointingHandCursor);                // 将鼠标浮动设置为手形状
    ui->confirm_visible->setCursor(Qt::PointingHandCursor);
    ui->pass_visible->SetState("unvisible", "unvisible_hover", "",      // 设置可点击标签的状态
                               "visible", "visible_hover", "");
    ui->confirm_visible->SetState("unvisible", "unvisible_hover", "",
                               "visible", "visible_hover", "");
    connect(ui->pass_visible, &ClickedLabel::clicked, this, [this](){   // 连接点击事件更改密码输入框的显示模式
       auto state = ui->pass_visible->GetCurState();
       if (state == ClickLbState::Normal) {
           ui->pass_edit->setEchoMode(QLineEdit::Password);
       } else {
           ui->pass_edit->setEchoMode(QLineEdit::Normal);
       }
    });
    connect(ui->confirm_visible, &ClickedLabel::clicked, this, [this](){
       auto state = ui->confirm_visible->GetCurState();
       if (state == ClickLbState::Normal) {
           ui->confirm_edit->setEchoMode(QLineEdit::Password);
       } else {
           ui->confirm_edit->setEchoMode(QLineEdit::Normal);
       }
    });

    // 初始化页面跳转的定时器及槽函数
    _countdown_timer = new QTimer(this);
    connect(_countdown_timer, &QTimer::timeout, this, [this](){
        if (_countdown == 0) {
            _countdown_timer->stop();
            emit sigSwitchLogin();
            return;
        }
        _countdown --;
        auto str = QString("注册成功，%1 s后返回登录").arg(_countdown);
        ui->tip_lable->setText(str);
    });
}

RegisterDialog::~RegisterDialog()
{
    delete ui;
}

void RegisterDialog::showTip(QString str, bool b_ok)
{
    if (b_ok) {
        ui->err_tip->setProperty("state", "normal");
    } else {
        ui->err_tip->setProperty("state", "err");
    }
    ui->err_tip->setText(str);

    repolish(ui->err_tip);
}

void RegisterDialog::initHttpHandlers()
{
    // 注册获取验证码回包逻辑
    _handlers.insert(ReqId::ID_GET_VARIFY_CODE, [this](QJsonObject jsonObj) {
        int error = jsonObj["error"].toInt();
        if (error != ErrorCodes::SUCCESS) {
            showTip(tr("参数错误"), false);
            return;
        }
        auto email = jsonObj["email"].toString();
        showTip(tr("验证码已发送到邮箱，请注意查收"), true);
        qDebug() << "request verify code email is " << email;
    });

    // 注册用户注册回包逻辑
    _handlers.insert(ReqId::ID_REG_USER, [this](QJsonObject jsonObj) {
        int error = jsonObj["error"].toInt();
        if (error != ErrorCodes::SUCCESS) {
            showTip(tr("参数错误"), false);
            return;
        }
        auto uid = jsonObj["uid"].toString();
        auto email = jsonObj["email"].toString();
        auto user = jsonObj["user"].toString();
        showTip(tr("用户注册成功"), true);
        qDebug() << "reg uid: "<< uid << "email is " << email << " user: " << user;
        ChangeTipPage();
    });
}

void RegisterDialog::AddTipErr(TipErr te, QString tips)
{
    _tip_errs[te] = tips;
    showTip(tips, false);
}

void RegisterDialog::DelTipErr(TipErr te)
{
    _tip_errs.remove(te);
    if (_tip_errs.empty()) {
        ui->err_tip->clear();
        return;
    }
    showTip(_tip_errs.first(), false); // _tip_errs[smallest key]
}

bool RegisterDialog::checkUserValid()
{
    if (ui->user_edit->text() == "") {
        AddTipErr(TipErr::TIP_USER_ERR, "用户名不能为空");
        return false;
    }
    DelTipErr(TipErr::TIP_USER_ERR);
    return true;
}

bool RegisterDialog::checkEmailValid()
{
    auto email = ui->email_edit->text();
    // 邮箱地址的正则表达式
    QRegularExpression regex(R"((\w+)(\.|_)?(\w*)@(\w+)(\.(\w+))+)");
    bool match = regex.match(email).hasMatch();
    if (!match) {
        AddTipErr(TipErr::TIP_EMAIL_ERR, "邮箱地址不正确");
        return false;
    }
    DelTipErr(TipErr::TIP_EMAIL_ERR);
    return true;
}

bool RegisterDialog::checkPassValid()
{
    auto pass = ui->pass_edit->text();
    if (pass.size() < 6 || pass.size() > 15) {
        AddTipErr(TipErr::TIP_PWD_ERR, "密码长度应为6~15位");
        return false;
    }
    QRegularExpression regex("^[a-zA-Z0-9!@#$%^&*]{6,15}$");
    bool match = regex.match(pass).hasMatch();
    if (!match) {
        AddTipErr(TipErr::TIP_EMAIL_ERR, "不能包含非法字符");
        return false;
    }
    DelTipErr(TipErr::TIP_PWD_ERR);
    return true;
}

bool RegisterDialog::checkConfirmValid()
{
    auto pass = ui->pass_edit->text();
    auto confirm = ui->confirm_edit->text();
    if (pass != confirm) {
        AddTipErr(TipErr::TIP_PWD_CONFIRM_ERR, "两次密码不一致");
        return false;
    }
    DelTipErr(TipErr::TIP_PWD_CONFIRM_ERR);
    return true;
}

bool RegisterDialog::checkVerifyValid()
{
    if (ui->verify_edit->text() == "") {
        AddTipErr(TipErr::TIP_VERIFY_ERR, "验证码不能为空");
        return false;
    }
    DelTipErr(TipErr::TIP_VERIFY_ERR);
    return true;
}

void RegisterDialog::on_get_code_clicked()
{
    auto email = ui->email_edit->text();
    // 邮箱地址的正则表达式
    QRegularExpression regex(R"((\w+)(\.|_)?(\w*)@(\w+)(\.(\w+))+)");
    bool match = regex.match(email).hasMatch();
    if (match) {
        // 发送http请求获取验证码
        QJsonObject json_obj;
        json_obj["email"] = email;
        QUrl post_url = QUrl(gate_url_prefix + "/get_verifycode");
        HttpMgr::GetInstance()->PostHttpReq(post_url,
                                            json_obj, ReqId::ID_GET_VARIFY_CODE, Modules::REGISTERMOD);
    } else {
        // 提示邮箱地址不正确
        showTip("邮箱地址不正确", false);
    }
}

void RegisterDialog::slot_reg_mod_finish(ReqId req_id, QString res, ErrorCodes err)
{
    if (err != ErrorCodes::SUCCESS) {
        showTip("网络请求错误", false);
        return;
    }

    // 将Json字符串转成JsonDocument来反序列化成对象
    QJsonDocument jsonDoc = QJsonDocument::fromJson(res.toUtf8());

    if (jsonDoc.isNull()) {
        showTip("json为空", false);
        return;
    }

    if (!jsonDoc.isObject()) {
        showTip("json解析错误", false);
        return;
    }

    // 调用对应的逻辑
    _handlers[req_id](jsonDoc.object());
    return;
}


void RegisterDialog::on_sure_btn_clicked()
{
    // 检查是否所有输入都符合要求
    if (!checkUserValid())    { return; }
    if (!checkEmailValid())   { return; }
    if (!checkPassValid())    { return; }
    if (!checkConfirmValid()) { return; }
    if (!checkVerifyValid())  { return; }

    QJsonObject jsonObj;
    jsonObj["user"] = ui->user_edit->text();
    jsonObj["email"] = ui->email_edit->text();
    jsonObj["passwd"] = ui->pass_edit->text();
    jsonObj["verifycode"] = ui->verify_edit->text();

    QUrl post_url = QUrl(gate_url_prefix + "/user_register");
    HttpMgr::GetInstance()->PostHttpReq(post_url,
                                        jsonObj, ReqId::ID_REG_USER, Modules::REGISTERMOD);
}

void RegisterDialog::ChangeTipPage()
{
    _countdown_timer->stop();
    ui->stackedWidget->setCurrentWidget(ui->page_2);

    // 启动定时器，设置间隔为1000ms（1s）
    _countdown_timer->start(1000);
}


void RegisterDialog::on_return_btn_clicked()
{
    _countdown_timer->stop();
    emit sigSwitchLogin();
}


void RegisterDialog::on_cancel_btn_clicked()
{
    _countdown_timer->stop();
    emit sigSwitchLogin();
}

